Use case: HASH process suspending and resuming in IT mode

Sequence diagram

  @startuml
   participant "Application" as App
   participant "HASH " as HASH
   participant "NVIC" as nvic

   == HASH Initialization and Configuration ==
   App->HASH : HAL_HASH_Init()
   note right : Configure the HASH  \n with SHA1 and data swapping
   == Process 1 : Low priority block computing HASH processing IT mode ==
   App->HASH : HAL_HASH_SHA1_Accmlt_IT()
   note right: start processing in IT mode
   App->HASH : HAL_HASH_SwFeed_ProcessSuspend()
   note right: Set the handle field SuspendRequest to the appropriate value so that \
   \n the on-going HASH processing is suspended as soon as the required \
   \nconditions are met \
   \n  Note that on some devices, the suspend request may be performed by calling **HAL_HASH_ProcessSuspend()**
   nvic -> HASH : HAL_HASH_IRQHandler()
   App->HASH : while (HAL_HASH_GetState() == HAL_HASH_STATE_SUSPENDED)
   note right: wait until processing is suspended
   App->HASH : HAL_HASH_ContextSaving()
   note right: - save the HASH context in an allocated buffer memory \n \n - Note that on some devices, the context is saved by calling **HAL_HASH_Suspend()**

   == Process 2 : High priority block computing HMAC processing IT mode ==
   App->HASH : HAL_HASH_Init()
   note right : Configure the HMAC with \n including the key and the key size
   App->HASH : HAL_HMACHEx_SHA256_Start_IT()
   note right : Compute and read the HMAC digest returned via a pointer
   nvic -> HASH : HAL_HASH_IRQHandler()
   HASH -> App: HAL_HASH_DgstCpltCallback()
   == Process 1 : Resuming HASH processing IT mode  ==
   App->HASH : HAL_HASH_ContextRestoring()
   note right : - restore all the context swap registers \n \n - Note that on some devices, the context is restored by calling **HAL_HASH_Resume()**
   nvic -> HASH : HAL_HASH_IRQHandler()
   note right : the previous IT process is resumed
   HASH--> App : HAL_HASH_InCpltCallback()
   App->HASH : HAL_HASH_SHA1_Accmlt_End_IT()
   note right: the HASH peripheral feed the rest of the input buffer \n and retrieve the diest
   nvic -> HASH : HAL_HASH_IRQHandler()
  HASH -> App: HAL_HASH_InCpltCallback() \n HAL_HASH_DgstCpltCallback()
   == HASH De-initialization  ==
   App->HASH : HAL_HASH_DeInit()

  @enduml

Code snippet

HAL1

HAL2

uint8_t Input[261] =
{0x54,0x68,0x65,0x20,0x68,0x61,0x73,0x68,
0x20,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,
0x6f,0x72,0x20,0x69,0x73,0x20,0x61,0x20,
0x66,0x75,0x6c,0x6c,0x79,0x20,0x63,0x6f,
0x6d,0x70,0x6c,0x69,0x61,0x6e,0x74,0x20,
0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,
0x66,0x20,0x74,0x68,0x65,0x20,0x73,0x65,
0x63,0x75,0x72,0x65,0x20,0x68,0x61,0x73,
0x68,0x20,0x61,0x6c,0x67,0x6f,0x72,0x69,
0x74,0x68,0x6d,0x20,0x28,0x53,0x48,0x41,
0x2d,0x31,0x29,0x2c,0x20,0x74,0x68,0x65,
0x20,0x4d,0x44,0x35,0x20,0x28,0x6d,0x65,
0x73,0x73,0x61,0x67,0x65,0x2d,0x64,0x69,
0x67,0x65,0x73,0x74,0x20,0x61,0x6c,0x67,
0x6f,0x72,0x69,0x74,0x68,0x6d,0x20,0x35,
0x29,0x20,0x68,0x61,0x73,0x68,0x20,0x61,
0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
0x20,0x61,0x6e,0x64,0x20,0x74,0x68,0x65,
0x20,0x48,0x4d,0x41,0x43,0x20,0x28,0x6b,
0x65,0x79,0x65,0x64,0x2d,0x68,0x61,0x73,
0x68,0x20,0x6d,0x65,0x73,0x73,0x61,0x67,
0x65,0x20,0x61,0x75,0x74,0x68,0x65,0x6e,
0x74,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,
0x20,0x63,0x6f,0x64,0x65,0x29,0x20,0x61,
0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
0x20,0x73,0x75,0x69,0x74,0x61,0x62,0x6c,
0x65,0x20,0x66,0x6f,0x72,0x20,0x61,0x20,
0x76,0x61,0x72,0x69,0x65,0x74,0x79,0x20,
0x6f,0x66,0x20,0x61,0x70,0x70,0x6c,0x69,
0x63,0x61,0x74,0x69,0x6f,0x6e,0x73,0x2e,
0x2a,0x2a,0x2a,0x20,0x53,0x54,0x4d,0x33,
0x32,0x20,0x2a,0x2a,0x2a};
uint8_t Msg3_Input[3] __attribute__ ((aligned (128)))= {
0x61, 0x62, 0x63};
uint8_t Sha1output[20]={0};
uint8_t Storage_Buffer[57*4] = {0};
HASH_HandleTypeDef hhash_saved;

/* HASH Initialization and configuration */
hhash.Init.DataType =  HASH_DATATYPE_8B;
HAL_HASH_Init(&hhash);




/* process 1 : Low-priority block computing in HASH processing mode  */
HAL_HASH_SHA1_Accmlt_IT(&hhash, Input, 64);
HAL_HASH_SwFeed_ProcessSuspend(&hhash);
/* wait until processing is suspended */
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_SUSPENDED);
/* save the context into a raw memory buffer  */
HAL_HASH_ContextSaving(&hhash, Storage_Buffer);
/* save low-priority block HASH handle parameters */
hhash_saved = hhash;

/* process 2: High-priority block computing in HMAC processing mode */
hhash.Init.DataType = HASH_DATATYPE_8B;
hhash.Init.pKey = Input;
hhash.Init.KeySize = 261;
HAL_HASH_Init(&hhash);

HAL_HMACEx_SHA256_Start_IT(&hhash, Msg3_Input, 3, Sha1output);

while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_READY);

/* Resume process 1 */
/* Context restoring operation */
HAL_HASH_ContextRestoring(&hhash, Storage_Buffer);
hhash = hhash_saved;

/* feeding input buffer */
HAL_HASH_SHA1_Accmlt_IT(&hhash, Input+64, 128);
/* wait until input completion callback */
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_READY);
/* feeding last data and retrieve the computed digest */
HAL_HASH_SHA1_Accmlt_End_IT(&hhash, Input+192, 69, &Sha1output);
/* wait until digest computation callback */
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_READY);




/* De-initialization */
HAL_HASH_DeInit(&hhash);
uint8_t Input[261] =
{0x54,0x68,0x65,0x20,0x68,0x61,0x73,0x68,
0x20,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,
0x6f,0x72,0x20,0x69,0x73,0x20,0x61,0x20,
0x66,0x75,0x6c,0x6c,0x79,0x20,0x63,0x6f,
0x6d,0x70,0x6c,0x69,0x61,0x6e,0x74,0x20,
0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,
0x66,0x20,0x74,0x68,0x65,0x20,0x73,0x65,
0x63,0x75,0x72,0x65,0x20,0x68,0x61,0x73,
0x68,0x20,0x61,0x6c,0x67,0x6f,0x72,0x69,
0x74,0x68,0x6d,0x20,0x28,0x53,0x48,0x41,
0x2d,0x31,0x29,0x2c,0x20,0x74,0x68,0x65,
0x20,0x4d,0x44,0x35,0x20,0x28,0x6d,0x65,
0x73,0x73,0x61,0x67,0x65,0x2d,0x64,0x69,
0x67,0x65,0x73,0x74,0x20,0x61,0x6c,0x67,
0x6f,0x72,0x69,0x74,0x68,0x6d,0x20,0x35,
0x29,0x20,0x68,0x61,0x73,0x68,0x20,0x61,
0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
0x20,0x61,0x6e,0x64,0x20,0x74,0x68,0x65,
0x20,0x48,0x4d,0x41,0x43,0x20,0x28,0x6b,
0x65,0x79,0x65,0x64,0x2d,0x68,0x61,0x73,
0x68,0x20,0x6d,0x65,0x73,0x73,0x61,0x67,
0x65,0x20,0x61,0x75,0x74,0x68,0x65,0x6e,
0x74,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,
0x20,0x63,0x6f,0x64,0x65,0x29,0x20,0x61,
0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
0x20,0x73,0x75,0x69,0x74,0x61,0x62,0x6c,
0x65,0x20,0x66,0x6f,0x72,0x20,0x61,0x20,
0x76,0x61,0x72,0x69,0x65,0x74,0x79,0x20,
0x6f,0x66,0x20,0x61,0x70,0x70,0x6c,0x69,
0x63,0x61,0x74,0x69,0x6f,0x6e,0x73,0x2e,
0x2a,0x2a,0x2a,0x20,0x53,0x54,0x4d,0x33,
0x32,0x20,0x2a,0x2a,0x2a};
uint8_t Msg3_Input[3] __attribute__ ((aligned (128)))= {
0x61, 0x62, 0x63};
uint8_t Sha1output[20]={0};
uint32_t sha1output_size;
hal_hash_suspended_context_t hash_ctx;

/* HASH Initialization */
HAL_HASH_Init(&hhash, HAL_HASH);
/* Configure HASH SHA1 algorithm */
hash_cfg.data_swapping  = HAL_HASH_DATA_SWAP_BYTE;
hash_cfg.algorithm = HAL_HASH_ALGO_SHA1;
HAL_HASH_SetConfig(&hhash, &hash_cfg);

/* process 1: Low-priority block computing in HASH processing mode */
HAL_HASH_Update_IT(&hhash, Input, 64);
HAL_HASH_RequestSuspendComputation(&hash);
/* wait until suspend callback is invoked */
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_SUSPENDED);
/* Context saving operation */
HAL_HASH_SaveContext(&hhash, &hash_ctx);



/* process 2: High-priority block computing in HMAC processing mode */
hash_hmac_cfg.data_swapping  = HAL_HASH_DATA_SWAP_BYTE;
hash_hmac_cfg.algorithm = HAL_HASH_ALGO_SHA256;
hash_hmac_cfg.key_size_byte = 3;
hash_hmac_cfg.p_key = Msg3_Input;
HAL_HASH_HMAC_SetConfig(&hhash, &hash_hmac_cfg);
HAL_HASH_HMAC_Compute_IT(&hhash, Msg3_Input, 3, Sha1output, 32, &sha1output_size);
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_IDLE);

/* Resume process 1 */
/* Context restoring operation */
HAL_HASH_RestoreContext(&hhash, &hash_ctx);
HAL_HASH_ResumeUpdate(&hhash);

/* feeding input buffer */
HAL_HASH_Update_IT(&hhash, Input+64, 128);
/* wait until input completion callback */
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_IDLE);
/* feeding the last input buffer */
HAL_HASH_Update_IT(&hhash, Input+192, 69);
/* wait until input completion callback */
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_IDLE);
/* retrieve the computed digest */
HAL_HASH_Finish(&hhash, Sha1output, 20, &sha1output_size, 1);
/* wait until digest computation callback */
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_IDLE);
/* De-initialization */
HAL_HASH_DeInit(&hhash);

Key changes

  1. HAL2 provides dedicated suspend/resume functions and a context structure for saving and restoring the HASH state.

  2. HAL2 uses unified APIs for HASH and HMAC configuration and computing, allowing switching between processes while preserving a suspended context.